package com.lintf.starter.central.auth.redis;

import com.lintf.starter.central.auth.CustomToken;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * 默认的Redis操作实现类，用于处理与认证相关的Redis操作。
 * 该类实现了RedisOperationsAdapter接口，提供了一系列针对CustomToken的操作方法。
 */
public class DefaultRedisOperator implements RedisOperationsAdapter {

    // RedisTemplate用于执行实际的Redis操作
    private final RedisTemplate<String, CustomToken> redisTemplate;

    /**
     * 构造函数，初始化RedisTemplate并配置序列化器。
     *
     * @param connectionFactory Redis连接工厂，用于创建Redis连接
     */
    public DefaultRedisOperator(RedisConnectionFactory connectionFactory) {
        this.redisTemplate = new RedisTemplate<>();
        this.redisTemplate.setConnectionFactory(connectionFactory);
        configureSerializers();
        this.redisTemplate.afterPropertiesSet();
    }

    /**
     * 配置RedisTemplate的序列化器。
     * 使用StringRedisSerializer作为键的序列化器，
     * 使用自定义的CustomTokenRedisSerializer作为值的序列化器。
     */
    private void configureSerializers() {
        // Key 序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // Value 序列化器 - 使用我们的自定义序列化器
        RedisSerializer<CustomToken> valueSerializer = new CustomTokenRedisSerializer();
        redisTemplate.setValueSerializer(valueSerializer);
        redisTemplate.setHashValueSerializer(valueSerializer);
    }

    /**
     * 存储Token到Redis。
     *
     * @param key        存储Token的键
     * @param token      要存储的CustomToken对象
     * @param ttlSeconds Token的存活时间（秒）
     */
    @Override
    public void setToken(String key, CustomToken token, long ttlSeconds) {
        redisTemplate.opsForValue().set(key, token, Duration.ofSeconds(ttlSeconds));
    }

    /**
     * 从Redis获取Token。
     *
     * @param key 获取Token的键
     * @return 对应键的CustomToken对象，如果不存在则返回null
     */
    @Override
    public CustomToken getToken(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 检查Redis中是否存在指定键的Token。
     *
     * @param key 要检查的键
     * @return 如果存在对应键的Token则返回true，否则返回false
     */
    @Override
    public boolean exists(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 从Redis删除指定键的Token。
     *
     * @param key 要删除的Token的键
     */
    @Override
    public void deleteToken(String key) {
        redisTemplate.delete(key);
    }
}
